package gui

import ewu._
import javax.swing.JTree
import javax.swing.tree.DefaultMutableTreeNode
import javax.swing.tree.DefaultTreeModel
import javax.swing.tree.TreeNode
import javax.swing.tree.TreePath
import javax.swing.tree.TreeSelectionModel
import scala.swing.Component
import scala.swing.SequentialContainer
import action._
import java.awt.event.MouseAdapter
import java.awt.event.MouseEvent
import java.io.File
import java.util._
import java.io.FileInputStream
import java.io.FileOutputStream
import lang.LOC

/**
 * Diese Klasse wrapped die java.swing-Klasse JTree.
 * Sie enthaelt Funktionen fuer das Hinzufuegen neuer
 * Children zum Baum sowie die MouseListener fuer
 * die Doppelklick-Funktion zum Oeffnen einer Datei
 * im Programm aus dem Baum heraus.
 */

class Tree (tt: Layout) extends Component with SequentialContainer.Wrapper {

 override lazy val peer = new JTree(new DefaultTreeModel(root)) {
   
    addMouseListener(new MouseAdapter() {
      override def mouseClicked(e: MouseEvent): Unit = {
        if(e.getClickCount() == 2 && e.getButton == MouseEvent.BUTTON1) {
          var x = e.getX();
          var y = e.getY();
          if (getRowForLocation(x, y) == -1) return null;
          var node:DefaultMutableTreeNode = getPathForLocation(x, y).
                                                    getLastPathComponent() match {
            case x:DefaultMutableTreeNode => x
            case _ => null
          };
          
            
          if(node != null) {
            if(node.getChildCount == 0) {
              var tmp = node.getUserObjectPath
              var adr = ""
              for(i <- 1 to tmp.length-1) {
                if(i != 1) {
                  adr += "\\"
                }
                adr += tmp(i)
              }
              var proj = tt.getProjectWithFile(new File(adr))
              if(proj == null) {
                var newpane = new ScrollTextAreaPane(true) {
                  setText(scala.io.Source.fromFile(adr).mkString)
                }
                tt.tabstop.addTab(node.toString, newpane)
                tt.newProject(node.toString, new File(adr), tt.tabstop, newpane)
                tt.tabstop.setSelectedIndex(tt.tabstop.peer.getTabCount()-1)
              }
              else {
                tt.setActivProject(proj)
              }
            }
          }
        }
      }
     })
  }
  
  var root: DefaultMutableTreeNode = new DefaultMutableTreeNode("ROOT")
  
  var treemodel = new DefaultTreeModel(root)
  peer.setModel(treemodel)
  
  peer.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION)
  peer.setRootVisible(false)

  def addNode(nod: Object, where: DefaultMutableTreeNode) : DefaultMutableTreeNode = {
    var newnode = new DefaultMutableTreeNode(nod)
    where.add(newnode)
    return newnode
  }
  
  def getHead() : DefaultMutableTreeNode = root
  
  def getModel() : DefaultTreeModel = treemodel
  
  def setRoot(o:Object) {
    o match {
      case x:DefaultMutableTreeNode => root = x;
      case x => root = new DefaultMutableTreeNode(x); 
    }
    treemodel = new DefaultTreeModel(root)
    peer.setModel(treemodel)
  }
  
  def getRoot() : Object = {
    return peer.getModel().getRoot()
  }
  
  def expandAll(expand: Boolean, tree: JTree = this.peer) : Unit = {
    var root = tree.getModel().getRoot() match {
      case x:TreeNode => x
    }
    expandAll(tree, new TreePath(root), expand)
    tree.setScrollsOnExpand(false)
    //tree.expandPath(new TreePath(root))
  } 
  
  def expandAll(tree: JTree, parent: TreePath, expand: Boolean) : Unit = {
    var node = parent.getLastPathComponent() match {
      case x:TreeNode => x
    }

    var onlyfiles = true
    if(node.getChildCount() >= 0) {
      var e = node.children()
      while(e.hasMoreElements) {
        var n = e.nextElement() match {
          case x:TreeNode => x
        }
        var path = parent.pathByAddingChild(n)
        expandAll(tree, path, expand)
        if(n.getChildCount() > 0)
          onlyfiles = false
      }
    }
    
    if(expand) {
      tree.expandPath(parent)
    } else {
      tree.collapsePath(parent)
    }
  }
  
}


 